<?php
/**
 *阿里大鱼
 * User: 梁晓伟  lxw11109@gmail.com
 * Date: 2017-09-04
 * Time: 15:10
 */

namespace App\Libs\Contracts\SMS;


use App\Libs\Contracts\SmsInterface;
use App\Libs\Sms\AliSms;
use Illuminate\Support\Facades\DB;

class AliImpl implements SmsInterface
{

    public function __construct()
    {
    }

    /**
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param \App\Libs\Contracts\验证码类型 $type
     * @param string $bz
     * @return array
     */
    public function send($mobile, $type, $bz='')
    {
        return $this->sendsms($mobile, $type, $bz);
    }

    /**
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param \App\Libs\Contracts\发送类型 $type
     * @param \App\Libs\Contracts\验证码 $smscode
     * @return array
     */
    public function check($mobile, $type, $smscode)
    {
        return $this->checkReturn($mobile, $type, $smscode);
    }

    /**
     * 验证短信校验码
     * @param $mobile
     * @param $type
     * @param $smscode
     * @return int
     */
    protected function checksms($mobile, $type, $smscode)
    {
        //检测手机校验码是否过期
        $smstime = substr(session('sms_time_'.$type), 0, strpos(session('sms_time_'.$type), '_'));
        $over = time() - $smstime;
        if ($over >= 60*10) {
            return -100;
        }
        $condition = array();
        $condition['code_phone'] = $mobile;
        $condition['code_type']  = $type;
        $condition['send_time'] = $sendtime = substr(session('sms_time_'.$type) , 0 , strpos(session('sms_time_'.$type), '_'));
        $data = DB::table('code_record')->where($condition)->first();

        if (!$data) {
            return -200;
        }
        if ($data->validate_state == '1' && $data->code == $smscode) {
            // 设置效验码已验证
            DB::update('update mall_code_record set validate_state = 2 where code_phone = ? and code_type = ? and send_time = ?', [$mobile, $type, $sendtime]);
            session(['sms_time_'.$type => null]); // 删除SESSION内容
            return  100;
        } else {
            return -300;
        }
    }

    /**
     * 发送短信
     *
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param $type
     * @param \App\Libs\Contracts\内容 $content
     */
    public function sendOnly($mobile, $type, $content)
    {
        $sms = new AliSms();
        list($sms_type, $content) = $this->getTypeContent($type);
        $sms_res = $sms->send($mobile, $sms_type, $content);
    }


    protected function makesms($type, $phone, $code)
    {
        $condition=array();
        $condition['code_type'] = $type;
        $condition['code_phone'] = $phone;
        $condition['validate_state'] = "1";
        $data = DB::table('code_record')->whereBetween('send_time',[time()-60, time()])->where($condition)->first();
        if (!empty($data)) {
            return -200;
        } else {
            $stime = strtotime(date('Y-m-d', time()));
            $etime = time();
            $data = CodeRecord::whereBetween('send_time', [$stime, $etime])->where('code_phone', '=', $phone)->where('ip', '=', getenv("REMOTE_ADDR"))->get();

            if (count($data) > 50) {
                return -300; //发送次数已达上限
            } else {
                $sms = new AliSms(); //阿里大于接口
                list($sms_type, $content) = $this->getTypeContent($type, $code);
                $sms_res = $sms->send($phone, $sms_type, $content);
                if (!$sms_res) {
                    return -100;
                }
                $coderecord = new CodeRecord();
                $coderecord->code = $code;
                $coderecord->code_phone = $phone;
                $coderecord->validate_state = '1';
                $coderecord->code_type = $type;
                $coderecord->send_time = time();
                $coderecord->return_content = $sms_res;
                $coderecord->ip = getenv("REMOTE_ADDR");
                $insert_res = $coderecord->save();

                if ($insert_res) {
                    $session_key = 'sms_time'.'_'.$type;
                    $session_val = time().'_'.$type;
                    session([$session_key => $session_val]);
                    return 100;
                } else {
                    return -100;
                }
            }
        }
    }


    private function getTypeContent($type, $code)
    {
        $code_type = trim($type);
        $tpl_info = DB::table('code_templates')->where('code_name', '=', $code_type)->first();
        $code_rep =  $tpl_info->code_content;
        $code_smtype = $tpl_info->code_type;
        $param = explode(',', $code_rep);
        $param = $this->repParameter($param, $code);
        return [$code_smtype, $param];


        $message = ncReplaceText($tpl_info->content, $param);
        return $message;
    }


    protected function checkReturn($mobile, $type, $smscode)
    {
        $result = $this->checksms($mobile, $type, $smscode);
        $success = false;
        switch($result)
        {
            case '-200':
                $msg = '验证码错误';
                $resultcode = '-200';
                break;
            case '-300':
                $msg = '验证码已使用';
                $resultcode = '-300';
                break;
            case '-100':
                $msg = '验证码已过期';
                $resultcode = '-100';
                break;
            case '100':
                $msg = '验证码正确';
                $resultcode = '100';
                $success = true;
                break;
        }
        return [$success, $msg, $resultcode];
    }


    protected function sendsms($phone, $type, $bz='')
    {
        $code = mt_rand(100000, 999999);
        $result = $this->makesms($type, $phone, $code);
        $success = false;
        switch($result)
        {
            case '-200':
                $msg = '验证码已发送';
                $success = true;
                break;
            case '-300':
                $msg = '超出当天发送次数';
                break;
            case '-100':
                $msg = '验证码发送失败';
                break;
            case '100':
                $msg = '发送成功';
                $success = true;
                break;
        }
        return [$success, $msg];
    }


    private function repParameter($param = array(), $code = '')
    {
        static $array;
        $smstype = ['time' => time()];
        foreach ($smstype  as $key => $value) {
            if (in_array($key, $param)) {
                $array[$key] = (string)$value;
            }
        }
        $array['code'] = (string)$code;
        return json_encode($array);
    }
}